#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define PTR_SIZE 8
#define INT_SIZE 2

struct type {
	char *name;
	int size;
	struct mem *mems;
	struct type *next;
};

struct vtype {
	struct type *bt;
	int pt;
	int lv;
};

struct mem {
	char *name;
	int offset;
	struct vtype type;
	struct mem *next;
};

struct var {
	char *name;
	struct vtype type;
	int loc;
	struct var *next;
};

struct func {
	char *name;
	struct vtype type;
	int spe;
	int loc;
	struct func *next;
};

struct token {
	char *str;
	int len;
	struct token *next;
	struct token *prev;
};

union typtr {
	struct func *func;
	struct var *var;
	unsigned short int val;
	char vchar;
	struct token *token;
};

struct tree {
	struct tree *next;
	struct tree *down;
	struct vtype type;
	union typtr to;
	int toket;
};

//err.c
void error(char *err);
void tokerror(struct token*,struct token*,char*);
void treerror(struct tree *tree,char *err);

//textp.c
struct token *endbr(struct token*,struct token*);
struct token *stabr(struct token*,struct token*);
struct token *find_rightest(struct token*,struct token*,char*);
struct token *find_leftest(struct token*,struct token*,char*);
int tokis(struct token*,char*);
int toktoint(struct token*);
int is_letter(char);
int is_alnum(char);
int is_brack(struct token*);

//lex.c
struct token *splitoken(char*,char*);
void freetokens(struct token*);

//opers.c
struct token *binoper(struct token*);
struct token *unaryoper(struct token*);
struct token *sufoper(struct token*);
extern struct token operass,operure;

//syn.c
struct tree *gettree(struct token*,struct token*);
void freetree(struct tree*);

//sem.c
void typetree(struct tree*);

//var.c
struct var *add_var(struct token*,struct vtype,int);
void del_var();
struct var *find_var(struct token*);
extern struct var *lastvar;

//type.c
struct type *add_type(char*,int);
struct type *find_type(struct token*);
int size(struct vtype vt);
struct type *get_type(char *str);
struct mem *find_member(struct type*,struct token*);
struct type *def_struct();
struct type *pass_type();
struct type *tmp_type(struct token**);
int istypdef(struct token*);
extern struct type *types;
void freetypes();

//func.c
struct func *add_func(int);
struct vtype find_same(struct tree *tree,struct func *func);
struct func *find_func(struct tree*);
struct func *find_funcbt(struct token*);
struct func *get_func(char *str);
void freefuncs();

//asm.c
void setstack(int);
void set_top(int);
void label(int);
void jmp(int);
void jmpn(int);
void jmpp(int);
void pop_cmp(int);
void cmp_stack(int);
void ext_var(char*);
void glb_var(char*);
void set_var(char*,int);
void call_func(char*);
void ret_func();
void ext_func(char*);
void start_func(char*);
void set_param(int);
void push_loc(int);
void push_glob(char*);
void push_int(short);
void push_char(char);
void push_string(struct token*);
extern int stack;
extern int labels;

//init.c
void init();
void cleanup();
extern struct token *pass;
extern FILE *output;
extern struct type *tsame,*tvoid,*tint,*tchar;
extern struct var *retvar;

//run.c
void run_file();
void run_unit(int);
void run_block();
void assign_var(struct var*,struct tree*);

//rutree.c
void run_tree(struct tree*,int);

//main.c
void prtokoff(struct token*);
